home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / amyboard / xboard-3.3.pl0 / childio.c < prev    next >
C/C++ Source or Header  |  1995-08-12  |  8KB  |  261 lines

  1. /*
  2.  * childio.c -- set up communication with child processes $Id:
  3.  * childio.c,v 1.2 1994/11/12 19:31:41 mann Exp mann $
  4.  *
  5.  * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
  6.  * Enhancements Copyright 1992-95 Free Software Foundation, Inc.
  7.  *
  8.  * The following terms apply to Digital Equipment Corporation's copyright
  9.  * interest in XBoard:
  10.  * ------------------------------------------------------------------------
  11.  * All Rights Reserved
  12.  *
  13.  * Permission to use, copy, modify, and distribute this software and its
  14.  * documentation for any purpose and without fee is hereby granted,
  15.  * provided that the above copyright notice appear in all copies and that
  16.  * both that copyright notice and this permission notice appear in
  17.  * supporting documentation, and that the name of Digital not be
  18.  * used in advertising or publicity pertaining to distribution of the
  19.  * software without specific, written prior permission.
  20.  *
  21.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  22.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  23.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  24.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  25.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  26.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  27.  * SOFTWARE.
  28.  * ------------------------------------------------------------------------
  29.  *
  30.  * The following terms apply to the enhanced version of XBoard distributed
  31.  * by the Free Software Foundation:
  32.  * ------------------------------------------------------------------------
  33.  * This program is free software; you can redistribute it and/or modify
  34.  * it under the terms of the GNU General Public License as published by
  35.  * the Free Software Foundation; either version 2 of the License, or
  36.  * (at your option) any later version.
  37.  *
  38.  * This program is distributed in the hope that it will be useful,
  39.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  40.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  41.  * GNU General Public License for more details.
  42.  *
  43.  * You should have received a copy of the GNU General Public License
  44.  * along with this program; if not, write to the Free Software
  45.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  46.  * ------------------------------------------------------------------------
  47.  *
  48.  * See the file ChangeLog for a revision history.  */
  49.  
  50. /* This file splits into two entirely different pieces of code
  51.    depending on whether USE_PTYS is 1.  The whole reason for all
  52.    the pty nonsense is that select() does not work on pipes in System-V
  53.    derivatives (at least some of them).  This is a problem because
  54.    XtAppAddInput works by adding its argument to a select that is done
  55.    deep inside Xlib.
  56. */
  57.  
  58. #include <config.h>
  59.  
  60. #include <signal.h>
  61. #if HAVE_UNISTD_H
  62. # include <unistd.h>
  63. #endif
  64.  
  65. #include "common.h"
  66. #include "frontend.h"
  67.  
  68. #if !USE_PTYS
  69. /* This code is for systems where pipes work properly */
  70.  
  71. void SetUpChildIO(to_prog, from_prog)
  72.      int to_prog[2], from_prog[2];
  73. {
  74.     signal(SIGPIPE, SIG_IGN);
  75.     pipe(to_prog);
  76.     pipe(from_prog);
  77. }
  78.  
  79. #else /* USE_PTYS == 1 */
  80. /* This code is for all systems where we must use ptys */
  81.  
  82. #include <errno.h>
  83. #include <sys/stat.h>
  84. #include <sys/ioctl.h>
  85. #if HAVE_STROPTS_H
  86. # include <stropts.h>
  87. #endif /* HAVE_STROPTS_H */
  88. #if HAVE_SYS_FCNTL_H
  89. # include <sys/fcntl.h>
  90. #else /* not HAVE_SYS_FCNTL_H */
  91. # if HAVE_FCNTL_H
  92. #  include <fcntl.h>
  93. # endif /* HAVE_FCNTL_H */
  94. #endif /* not HAVE_SYS_FCNTL_H */
  95.  
  96. int PseudoTTY P((char pty_name[]));
  97.  
  98. int SetUpChildIO(to_prog, from_prog)
  99.      int to_prog[2], from_prog[2];
  100. {
  101.     char pty_name[MSG_SIZ];
  102.  
  103.     if ((to_prog[1] = PseudoTTY(pty_name)) == -1) {
  104.     DisplayFatalError("Can't open pseudo-tty", errno, 1);
  105.     ExitEvent(1);
  106.     }
  107.     from_prog[0] = to_prog[1];
  108.     to_prog[0] = from_prog[1] = open(pty_name, O_RDWR, 0);
  109.  
  110. #if HAVE_STROPTS_H /* do we really need this??  pipe-like behavior is fine */
  111.     if (ioctl (to_prog[0], I_PUSH, "ptem") == -1 ||
  112.     ioctl (to_prog[0], I_PUSH, "ldterm") == -1 ||
  113.     ioctl (to_prog[0], I_PUSH, "ttcompat") == -1) {
  114. # ifdef NOTDEF /* seems some systems don't have or need ptem and ttcompat */
  115.     DisplayFatalError("Can't ioctl pseudo-tty", errno, 1);
  116.     ExitEvent(1);
  117. # endif /*NOTDEF*/
  118.     }
  119. #endif /* HAVE_STROPTS_H */
  120.  
  121. }
  122.  
  123. #if HAVE_GRANTPT
  124. /* This code is for SVR4 */
  125.  
  126. int PseudoTTY(pty_name)
  127.      char pty_name[];
  128. {
  129.     extern char *ptsname();
  130.     char *ptss;
  131.     int fd;
  132.     
  133.     fd = open("/dev/ptmx", O_RDWR);
  134.     if (fd < 0) return fd;
  135.     if (grantpt(fd) == -1) return -1;
  136.     if (unlockpt(fd) == -1) return -1;
  137.     if (!(ptss = ptsname(fd))) return -1;
  138.     strcpy(pty_name, ptss);
  139.     return fd;
  140. }
  141.  
  142. #else /* not HAVE_GRANTPT */
  143. #if HAVE__GETPTY
  144. /* This code is for IRIX */
  145.  
  146. int PseudoTTY(pty_name)
  147.      char pty_name[];
  148. {
  149.     int fd;
  150.     char *ptyn;
  151.  
  152.     ptyn = _getpty(&fd, O_RDWR, 0600, 0);
  153.     if (ptyn == NULL) return -1;
  154.     strcpy(pty_name, ptyn);
  155.     return fd;
  156. }
  157.  
  158. #else /* not HAVE__GETPTY */
  159. #if HAVE_LIBSEQ
  160. /* This code is for Sequent DYNIX/ptx.  Untested. --tpm */
  161.  
  162. int PseudoTTY(pty_name)
  163.      char pty_name[];
  164. {
  165.     int fd;
  166.     char *slave, *master;
  167.  
  168.     fd = getpseudotty(&slave, &master);
  169.     if (fd < 0) return fd;
  170.     strcpy(pty_name, slave);
  171.     return fd;
  172. }
  173.  
  174. #else /* not HAVE_LIBSEQ */
  175. /* This code is for all other systems */
  176. /* The code is adapted from GNU Emacs 19.24 */
  177.  
  178. #ifndef FIRST_PTY_LETTER
  179. #define FIRST_PTY_LETTER 'p'
  180. #endif
  181. #ifndef LAST_PTY_LETTER
  182. #define LAST_PTY_LETTER 'z'
  183. #endif
  184.  
  185. int PseudoTTY(pty_name)
  186.      char pty_name[];
  187. {
  188.   struct stat stb;
  189.   register c, i;
  190.   int fd;
  191.  
  192.   /* Some systems name their pseudoterminals so that there are gaps in
  193.      the usual sequence - for example, on HP9000/S700 systems, there
  194.      are no pseudoterminals with names ending in 'f'.  So we wait for
  195.      three failures in a row before deciding that we've reached the
  196.      end of the ptys.  */
  197.   int failed_count = 0;
  198.  
  199. #ifdef PTY_ITERATION
  200.   PTY_ITERATION
  201. #else
  202.   for (c = FIRST_PTY_LETTER; c <= LAST_PTY_LETTER; c++)
  203.     for (i = 0; i < 16; i++)
  204. #endif
  205.       {
  206. #ifdef PTY_NAME_SPRINTF
  207.     PTY_NAME_SPRINTF
  208. #else
  209.     sprintf (pty_name, "/dev/pty%c%x", c, i);
  210. #endif /* no PTY_NAME_SPRINTF */
  211.  
  212. #ifdef PTY_OPEN
  213.     PTY_OPEN;
  214. #else /* no PTY_OPEN */
  215.     if (stat (pty_name, &stb) < 0)
  216.       {
  217.         failed_count++;
  218.         if (failed_count >= 3)
  219.           return -1;
  220.       }
  221.     else
  222.       failed_count = 0;
  223.     fd = open (pty_name, O_RDWR, 0);
  224. #endif /* no PTY_OPEN */
  225.  
  226.     if (fd >= 0)
  227.       {
  228.         /* check to make certain that both sides are available
  229.            this avoids a nasty yet stupid bug in rlogins */
  230. #ifdef PTY_TTY_NAME_SPRINTF
  231.         PTY_TTY_NAME_SPRINTF
  232. #else
  233.             sprintf (pty_name, "/dev/tty%c%x", c, i);
  234. #endif /* no PTY_TTY_NAME_SPRINTF */
  235. #ifndef UNIPLUS
  236.         if (access (pty_name, 6) != 0)
  237.           {
  238.         close (fd);
  239.         continue;
  240.           }
  241. #endif /* not UNIPLUS */
  242. #ifdef IBMRTAIX
  243.           /* On AIX, the parent gets SIGHUP when a pty attached
  244.                  child dies.  So, we ignore SIGHUP once we've started
  245.                  a child on a pty.  Note that this may cause xboard
  246.                  not to die when it should, i.e., when its own
  247.                  controlling tty goes away.
  248.           */
  249.           signal(SIGHUP, SIG_IGN);
  250. #endif /* IBMRTAIX */
  251.         return fd;
  252.       }
  253.       }
  254.   return -1;
  255. }
  256.  
  257. #endif /* not HAVE_LIBSEQ */
  258. #endif /* not HAVE__GETPTY */
  259. #endif /* not HAVE_GRANTPT */
  260. #endif /* USE_PTYS */
  261.